package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"fmt"
)

// 公私锁（非对称加密）：公钥上锁，私钥开锁
// 用私钥“签名”（证明是你发的）
func sign(data []byte, priv *rsa.PrivateKey) ([]byte, error) {
	hash := sha256.Sum256(data)
	return rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, hash[:])
}

// 用公钥“验证”签名（证明数据是真的、没被改）
func verifySignature(data, signature []byte, pub *rsa.PublicKey) bool {
	hash := sha256.Sum256(data)
	// 如果验证成功，err 为 nil
	err := rsa.VerifyPKCS1v15(pub, crypto.SHA256, hash[:], signature)
	return err == nil
}

func main() {
	// 1. 生成公私钥对（实际用的时候，私钥要安全保管，公钥可以公开）
	priv, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		fmt.Printf("生成密钥失败: %v\n", err)
		return
	}
	pub := &priv.PublicKey // 从私钥中提取公钥

	// 2. 要发送的数据
	data := []byte("我承诺：转账100元")
	fmt.Println("原始数据：", string(data))

	// 3. 使用私钥对数据进行签名
	signature, err := sign(data, priv)
	if err != nil {
		fmt.Printf("签名失败: %v\n", err)
		return
	}
	fmt.Printf("生成的签名（一串随机字节）：%x\n", signature)

	// --- 模拟数据传输和验证 ---

	// 场景A：数据和签名都完好无损地到达接收方
	fmt.Println("\n--- 场景A：数据完好 ---")
	correctData := []byte("我承诺：转账100元")
	isValid := verifySignature(correctData, signature, pub)
	fmt.Printf("数据验证结果:%v, 数据:%s, 签名:%x\n", isValid, string(correctData), signature)

	// 场景B：数据在传输过程中被恶意篡改（比如，金额从100改成了1000）
	fmt.Println("\n--- 场景B：数据被篡改 ---")
	tamperedData := []byte("我承诺：转账1000元")
	isValid = verifySignature(tamperedData, signature, pub)
	fmt.Printf("数据验证结果:%v, 数据:%s, 签名:%x\n", isValid, string(tamperedData), signature)

	// 场景C：数据完好，但签名被篡改
	fmt.Println("\n--- 场景C：签名被篡改 ---")
	// 模拟一个错误的签名
	tamperedSignature := []byte("this is a wrong signature")
	correctData = []byte("我承诺：转账100元")
	isValid = verifySignature(correctData, tamperedSignature, pub)
	fmt.Printf("数据验证结果:%v, 数据:%s, 签名:%x\n", isValid, string(correctData), tamperedSignature)
}
